from flask import Flask, request, send_from_directory, render_template, redirect, url_for, abort, jsonify
import os
from flask_cors import CORS, cross_origin
from werkzeug.utils import secure_filename
from datetime import datetime

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})  # 跨域请求
CORS(app, resources={r"/upload": {"origins": "http://localhost:85"}})  # 精确配置
UPLOAD_FOLDER = './shared'  # 共享文件夹路径
PORT = 888                  # 服务端口

# 配置参数
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024 * 1024  # 允许最大2GB文件
app.config['ALLOWED_EXTENSIONS'] = {'*'}                   # 允许所有文件类型

# 确保共享目录存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
print(f"UPLOAD_FOLDER: {UPLOAD_FOLDER}")

def human_readable_size(size_bytes):
    """转换文件大小为人类可读格式"""
    units = ('B', 'KB', 'MB', 'GB', 'TB')
    for unit in units:
        if size_bytes < 1024.0 or unit == 'TB':
            break
        size_bytes /= 1024.0
    return f"{size_bytes:.1f} {unit}"

@app.route('/')
def file_list():
    """显示共享目录文件列表"""
    files = []
    for filename in os.listdir(UPLOAD_FOLDER):
        filepath = os.path.join(UPLOAD_FOLDER, filename)
        if os.path.isfile(filepath):
            stat = os.stat(filepath)
            files.append({
                'name': filename,
                'size': human_readable_size(stat.st_size),
                'mtime': datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M'),
                'url': f"/download/{filename}"
            })
    return render_template('file_list.html', files=files)

# 访问静态文件路由
@app.route('/<path:filename>')
def static_files(filename):
    return send_from_directory(UPLOAD_FOLDER, filename)

# 下载文件路由
@app.route('/download', methods=['POST', 'OPTIONS'])
@cross_origin(origin='http://localhost:85',                 
              allow_headers=['Content-Type', 'Authorization'],
              supports_credentials=True)  # 新增凭证支持
def download_file():
    """提供文件下载"""
    file_path = request.json.get('file_path')
    try:
        return send_from_directory(
            app.config['UPLOAD_FOLDER'],
            file_path, 
            as_attachment=True,
            conditional=True
        )
    except FileNotFoundError:
        return jsonify({'error': 'File not found'}), 404

# 上传文件路由
@app.route('/upload', methods=['POST', 'OPTIONS'])  # 添加OPTIONS方法
@cross_origin(origin='http://localhost:85', 
              allow_headers=['Content-Type', 'Authorization'],
              supports_credentials=True)  # 新增凭证支持
def upload_file():
    """处理文件上传"""
    if 'file' not in request.files:
        return jsonify({'error': 'No file part'}), 400

    file = request.files['file']
    file_path = request.form.get('filePath', '')
    
    if file.filename == '':
        return jsonify({'error': 'No selected file'}), 400

    try:
        # 创建目录路径
        full_path = os.path.join(UPLOAD_FOLDER, file_path)
        os.makedirs(os.path.dirname(full_path), exist_ok=True)
        
        # 保存文件
        file.save(full_path)
        return jsonify({
            'status': 'success',
            'filePath': file_path
        }), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 删除文件路由
@app.route('/delete/<path:filename>', methods=['DELETE', 'OPTIONS'])  # 添加OPTIONS方法
@cross_origin(origin='http://localhost:85', 
              allow_headers=['Content-Type', 'Authorization'],
              supports_credentials=True)  # 新增凭证支持
def delete_file(filename):
    try:
        full_path = os.path.join(UPLOAD_FOLDER, filename)
        if not os.path.exists(full_path):
            return jsonify({'error': 'File not found'}), 404
        os.remove(full_path)
        return jsonify({'status': 'success'}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500


# HTML模板直接嵌入代码中
app.jinja_env.globals.update(human_readable_size=human_readable_size)

if not os.path.exists('templates'):
    os.makedirs('templates')
    
with open('templates/file_list.html', 'w', encoding='utf-8') as f:
    f.write('''<!DOCTYPE html>
<html>
<head>
    <title>文件共享服务</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .header { display: flex; justify-content: space-between; align-items: center; }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid #ddd; }
        th { background-color: #f2f2f2; font-weight: bold; }
        tr:hover { background-color: #f5f5f5; }
        .upload-form { margin: 20px 0; }
        .instructions { background: #f9f9f9; padding: 15px; border-radius: 5px; margin-top: 20px; }
        pre { background: #eee; padding: 10px; border-radius: 3px; overflow-x: auto; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>文件共享服务</h1>
            <p>端口: {{ port }}</p>
        </div>
        
        <div class="upload-form">
            <h2>上传文件</h2>
            <form method="post" enctype="multipart/form-data" action="/upload">
                <input type="file" name="file" required>
                <input type="submit" value="上传">
            </form>
        </div>

        <h2>共享文件列表</h2>
        {% if files %}
        <table>
            <thead>
                <tr>
                    <th>文件名</th>
                    <th>大小</th>
                    <th>修改时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                {% for file in files %}
                <tr>
                    <td>{{ file.name }}</td>
                    <td>{{ file.size }}</td>
                    <td>{{ file.mtime }}</td>
                    <td><a href="{{ file.url }}">下载</a></td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <p>共享目录为空</p>
        {% endif %}

        <div class="instructions">
            <h3>使用说明</h3>
            <p><strong>浏览器访问：</strong> <a href="http://localhost:{{ port }}">http://localhost:{{ port }}</a></p>
            
            <p><strong>命令行上传：</strong></p>
            <pre>curl -F "file=@本地文件路径" http://localhost:{{ port }}/upload</pre>
            
            <p><strong>命令行下载：</strong></p>
            <pre>curl -O http://localhost:{{ port }}/download/文件名</pre>
            <pre>wget http://localhost:{{ port }}/download/文件名</pre>
        </div>
    </div>
</body>
</html>''')

if __name__ == '__main__':
    print(f"文件共享服务已启动，访问 http://localhost:{PORT}")
    print(f"共享目录: {os.path.abspath(UPLOAD_FOLDER)}")
    app.run(host='0.0.0.0', port=PORT)